package util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* En base a strubsEndes.rar\strubsEndes\src\java\commons\ReflectUtil.java
* @author Rdelacruz 
*/
public class ReflectUtil {
	
    //private static void gestionarExcepcion(Exception e) {
    //    LoggerUtil.log(ReflectUtil.class,e);
    //}


    @SuppressWarnings("rawtypes")
    private static Class getClase(String clase) throws ClassNotFoundException {
        return Class.forName(clase);
    }	

    public static void mostrarTiposDatos() {
        System.out.println("Tipos de datos para los argumentos");
        System.out.println("int ="+Integer.TYPE);
        System.out.println("Integer ="+Integer.class);
        System.out.println("String ="+String.class);
    }
    
    public static Object getValorString(Object obj, String nombreAtributo) 
            throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Object v = getValor(obj,nombreAtributo);
        return v!=null ? v.toString() : null;
    }            
    
    public static Object getValor(Object obj, String nombreAtributo) 
            throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {		
        Field f = obj.getClass().getDeclaredField(nombreAtributo);
        return f.get(obj);
    }   

    @SuppressWarnings({ "rawtypes" })
    public static Field getAtributo(Class clase, String nombreAtributo) throws NoSuchFieldException {		
        return clase.getDeclaredField(nombreAtributo);
    }    

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Method getMetodo(Class clase, String metodo, Class tipoArgumento) throws NoSuchMethodException {
        if(clase!=null) {		
            return clase.getMethod(metodo,tipoArgumento);          
        }
        return null;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Method getMetodo(Class clase, String metodo, Class[] tiposArgumentos) throws NoSuchMethodException {
        if(clase!=null) {	              
            return clase.getMethod(metodo,tiposArgumentos);         
        }
        return null;
    }

    @SuppressWarnings({ "rawtypes" })
    public static Method getMetodo(String clase, String metodo, Class tipoArgumento) throws NoSuchMethodException, ClassNotFoundException {		
        return getMetodo(getClase(clase), metodo, tipoArgumento);
    }

    @SuppressWarnings({ "rawtypes" })
    public static Method getMetodo(String clase, String metodo, Class[] tiposArgumentos) throws NoSuchMethodException, ClassNotFoundException {		
            return getMetodo(getClase(clase), metodo, tiposArgumentos);
    }

    public static Method getMetodoGet(Class clase, String metodo) throws NoSuchMethodException {
        String primera=metodo.charAt(0)+"";		
        metodo = "get"+metodo.replaceFirst(primera, primera.toUpperCase());
        return getMetodo(clase,metodo,new Class[]{});
    }

    public static Method getMetodoSet(Class clase, String metodo, Class tipoArgumento) throws NoSuchMethodException {
        String primera=metodo.charAt(0)+"";		
        metodo = "set"+metodo.replaceFirst(primera, primera.toUpperCase());
        return getMetodo(clase,metodo,tipoArgumento);
    }        



///////////////////////////////////////////////////////////        


    @SuppressWarnings("rawtypes")
    public static Object invocar(Object instancia, Method metodo, Object[] argumentos) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if(metodo!=null && instancia!=null) {			
            return metodo.invoke(instancia,argumentos);           		
        }		
        return null;
    }

    @SuppressWarnings("rawtypes")
    public static Object invocar(Object instancia, Method metodo, Object argumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if(metodo!=null && instancia!=null) {			
            return metodo.invoke(instancia,argumento);		
        }		
        return null;
    }

    @SuppressWarnings("rawtypes")
    public static Object invocar(Object instancia, Class clase, String metodo, Object argumento, Class tipoArgumento) 
            throws IllegalAccessException, IllegalArgumentException, 
            InvocationTargetException, NoSuchMethodException {
        return invocar(instancia, getMetodo(clase,metodo,tipoArgumento), argumento);
    }

    @SuppressWarnings("rawtypes")
    public static Object invocar(Object instancia, Class clase, String metodo, Object[] argumentos, Class[] tiposArgumentos) 
            throws IllegalAccessException, IllegalArgumentException, 
            InvocationTargetException, NoSuchMethodException {		
        return invocar(instancia,getMetodo(clase,metodo,tiposArgumentos),argumentos);
    }        

    @SuppressWarnings({ "rawtypes" })
    public static Object invocar(Object instancia, String clase, String metodo, Object[] argumentos, Class[] tiposArgumentos) 
            throws IllegalAccessException, IllegalArgumentException, 
            InvocationTargetException, NoSuchMethodException, ClassNotFoundException {		
        return invocar(instancia, getMetodo(getClase(clase),metodo,tiposArgumentos), argumentos);
    }

    @SuppressWarnings({ "rawtypes" })
    public static Object invocar(Object instancia, String clase, String metodo, Object argumento, Class tipoArgumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, 
            NoSuchMethodException, ClassNotFoundException {		
        return invocar(instancia,getClase(clase), metodo, argumento, tipoArgumento);
    }


    //-----------------------------------------------------


    @SuppressWarnings("rawtypes")
    public static Object invocarSet(Object instancia, Class clase, String metodo, Object argumento, Class tipoArgumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        return invocar(instancia, getMetodoSet(clase, metodo, tipoArgumento), argumento );
    }	

    @SuppressWarnings("rawtypes")
    public static Object invocarGet(Object instancia, Class clase, String metodo) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        return invocar(instancia, getMetodoGet(clase, metodo), new Object[]{} );        
    }


    @SuppressWarnings({ "rawtypes" })
    public static Object invocarSet(Object instancia, String clase, String metodo, Object argumento, Class tipoArgumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, 
            NoSuchMethodException, ClassNotFoundException {		
        return invocarSet(instancia,getClase(clase), metodo, argumento, tipoArgumento);
    }        

    public static Object invocarGet(Object instancia, String clase, String metodo) 
            throws IllegalAccessException, IllegalArgumentException, 
            InvocationTargetException, NoSuchMethodException, ClassNotFoundException {		
        return invocarGet(instancia,getClase(clase), metodo);
    }		



    @SuppressWarnings("rawtypes")
    public static Object invocarSetInt(Object instancia, Class clase, String metodo, int argumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        return invocarSet(instancia,clase,metodo,argumento,Integer.TYPE);
    }		

    @SuppressWarnings("rawtypes")
    public static Object invocarSetInteger(Object instancia, Class clase, String metodo, Integer argumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        return invocarSet(instancia,clase,metodo,argumento,Integer.class);
    }
        
    public static Object invocarSetIntegerOInt(Object bean, Class beanClass, String name, Integer argumento) 
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Method met = getMetodoSet(beanClass,name,Integer.class);
        if(met==null)
            met = getMetodoSet(beanClass,name,Integer.TYPE);        
        return invocar(bean, met, argumento);        
    }        
	
    @SuppressWarnings("rawtypes")
    public static Object invocarSetString(Object instancia, Class clase, String metodo, String argumento) 
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        return invocarSet(instancia,clase,metodo,argumento,String.class);
    }


}
